home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / sysdep1.c < prev    next >
C/C++ Source or Header  |  1996-08-29  |  29KB  |  914 lines

  1. /************************************************************************/
  2. /*                              sysdep1.c                               */
  3. /*                                                                      */
  4. /*      This is the repository of most of the system dependent code     */
  5. /*      in Citadel.  We hope, pray, and proselytize, at least.          */
  6. /************************************************************************/
  7. /************************************************************************/
  8. /*                              history                                 */
  9. /*                                                                      */
  10. /* 89Oct16 AP   Amiga                                                   */
  11. /* 87Apr01 HAW  File tagging completed; bug for .RD/.RE fixed.          */
  12. /* 86Dec14 HAW  Reorganized into areas.                                 */
  13. /* 86Nov25 HAW  Created.                                                */
  14. /************************************************************************/
  15. #define SYSTEM_DEPENDENT
  16. #define TIMER_FUNCTIONS_NEEDED
  17. #include "ctdl.h"
  18. #include "dos.h"
  19. #include "time.h"
  20. #include "string.h"
  21. #include "stdarg.h"
  22. /************************************************************************/
  23. /*                              Contents                                */
  24. /*                                                                      */
  25. /*              AREAS:                                                  */
  26. /*      bigDirectory()          gets an "extended" directory            */
  27. /* #    bigDirs()               work function for bigDirectory()        */
  28. /*      freeFileList()          Free file list                          */
  29. /*      getArea()               get an area from the sysop              */
  30. /*      goodArea()              get good area                           */
  31. /*      homeSpace()             takes us to our home space              */
  32. /*      netGetArea()            get area for dumping networked file(s)  */
  33. /*      netSetNewArea()         set area for dumping networked file(s)  */
  34. /*      prtNetArea()            makes human readable form of NET_AREA   */
  35. /*      setSpace()              goto specified "area"                   */
  36. /* #    realSetSpace()          does work of setSpace, others           */
  37. /* #    MSDOSparse()            parses a string for MSDOS filename      */
  38. /* #    fileType()              gets file type for MSDOS                */
  39. /*      sysGetSendFiles()       specify where to send files from        */
  40. /*      updFiletag()            updates a filetag                       */
  41. /*      sysRoomLeft()           how much room left in net recept area   */
  42. /* #    getSize()               gets size of a file                     */
  43. /*      sysSendFiles()          system dep stuff for sending files      */
  44. /* #    doSendWork()            does work of sysSendFiles()             */
  45. /*              BAUD HANDLER:                                           */
  46. /* #    check_CR()              scan input for carriage returns         */
  47. /*      Find_baud()             does flip flop search for baud          */
  48. /*      getNetBaud()            check for baud of network caller        */
  49. /*              CONSOLE HANDLING:                                       */
  50. /*      KBReady()               returns TRUE if a console char is ready */
  51. /*      mputChar()              Do our own for some Console output      */
  52. /*                                                                      */
  53. /*              # == local for this implementation only                 */
  54. /************************************************************************/
  55. #define NO_IDEA         0
  56. #define SINGLE_FILE     1
  57. #define IS_DIR          2
  58. #define AMB_FILE        3
  59. /************************************************************************/
  60. /*      Globals -- there shouldn't be anything here but statics and     */
  61. /*      externs.                                                        */
  62. /************************************************************************/
  63. /* These MUST be defined! */
  64. short ConDelay;
  65. char *R_W_ANY     = "rb+";
  66. char *READ_ANY    = "rb";
  67. char *READ_TEXT   = "ra";
  68. char *APPEND_TEXT = "aa";
  69. char *APPEND_ANY  = "ab";
  70. char *A_C_TEXT    = "ab";
  71. char *WRITE_TEXT  = "wa";
  72. char *W_R_ANY     = "wb+";
  73. char *WRITE_ANY   = "wb";
  74. static FILE *fileTags;                  /* For the file tags            */
  75.  
  76. char results_debug=FALSE;  /* turn on to debug modem results codes */
  77. char results_cid=FALSE;    /* turn on to collect caller ID info if present */
  78.  
  79.  
  80. int Jsystem(char *);
  81. void Do_Stack_Check(void);
  82.  
  83. char *rates[] =
  84.   {
  85.   "300",   "1200",  "2400",   "4800",    "9600",
  86.   "14400", "19200", "38400", "57600", "Unknown"
  87.  
  88.   };
  89. static short LastBaudIndex;
  90.  
  91. /* Here's the rest of the goo */
  92. extern logBuffer logBuf;         /* Log buffer of a person       */
  93. extern SListBase ResList;
  94. extern aRoom     roomBuf;
  95. extern MessageBuffer   msgBuf;
  96. extern CONFIG    cfg;            /* Lots an lots of variables    */
  97. extern char onConsole;                  /* Who's in control?!?          */
  98. extern char whichIO;                    /* CONSOLE or MODEM             */
  99. extern char anyEcho;
  100. extern char echo;
  101. extern FILE *upfd;
  102. extern char modStat;
  103. extern char echoChar;
  104. extern char haveCarrier;
  105. extern long netBytes;
  106. extern char outFlag;
  107. extern char *indexTable;
  108. void *ChPhrase(DirEntry *e, DirEntry *d);
  109. /************************************************************************/
  110. /* Section 3.4. AREAS:                                                  */
  111. /*   The model of Citadel includes a provision for "directory rooms."   */
  112. /* A directory room is defined as the ability to look in on some section*/
  113. /* of the host system's file section.  In order to avoid tying the      */
  114. /* directory structure of Citadel to any particular operating system, an*/
  115. /* "abstraction" has been implemented.  Each room that has been desig-  */
  116. /* nated as a directory will have an "area" associated with it.  This   */
  117. /* "area" is dependent on each implementation; access to "areas" is     */
  118. /* through routines located in this module.  Therefore, the abstract    */
  119. /* directory model of Citadel is in the main code modules, and should   */
  120. /* not require any changes from port to port.  The only changes neces-  */
  121. /* sary should be in this file (SYSDEP.C), where the porter must decide */
  122. /* upon and implement a mapping of how a directory room peeks in on his */
  123. /* or her file system.                                                  */
  124. /*   Basically, the routines are fairly simple in purpose.              */
  125. /*                                                                      */
  126. /*      "And if pigs had wings they could fly!"                         */
  127. /************************************************************************/
  128. char        ourHomeSpace[150];
  129. char MatchList[] = ".-_*?";
  130. /************************************************************************/
  131. /*      ValidDirFileName() validate a file name                         */
  132. /************************************************************************/
  133. char ValidDirFileName(char *ptr)
  134.   {
  135.   Do_Stack_Check();
  136.   while (*ptr)
  137.     {
  138.     if (isalpha(*ptr) || isdigit(*ptr) || strchr(MatchList, *ptr))
  139.     ++ptr;
  140.     else
  141.     return FALSE;
  142.  
  143.     }
  144.   return TRUE;
  145.  
  146.   }
  147. /************************************************************************/
  148. /*      RoomLeft() how much room left on this disk or whatever?         */
  149. /*      NB: Returns in K, not bytes!                                    */
  150. /************************************************************************/
  151. long RoomLeft(aRoom *room)
  152.   {
  153.   char *temp, dir[150];
  154.   long temp3, temp2;
  155.   long toReturn;
  156.   /* this should never happen, but just in case ... */
  157.   Do_Stack_Check();
  158.   if ((temp = FindDirName(room->rbArea)) == NULL)  return 0;
  159.   strCpy(dir, temp);
  160.   diskSpaceLeft(dir, &temp3, &temp2);
  161.   toReturn = temp2 / 1024l;
  162.   return toReturn;
  163.  
  164.   }
  165.  
  166. /************************************************************************/
  167. /*      getArea() get area to assign to a directory room from sysop     */
  168. /*      returns FALSE if problems or abort                              */
  169. /************************************************************************/
  170. char getArea(aRoom *roomData)
  171.   {
  172.   char dir[200];
  173.   SYS_FILE filename;
  174.   extern char *DirFileName;
  175.   extern SListBase DirBase;
  176.   Do_Stack_Check();
  177.   if (!goodArea("DIRNAM", dir))
  178.     {
  179.     return FALSE;
  180.  
  181.     }
  182.   makeSysName(filename, DirFileName, &cfg.roomArea);
  183.   upfd = safeopen(filename, WRITE_TEXT);
  184.   AddData(&DirBase, NtoStrInit(roomData->rbArea, dir, 0, FALSE),
  185.   WrtNtoStr, /* Kill duplicates */ TRUE);
  186.   fclose(upfd);
  187.   return TRUE;
  188.  
  189.   }
  190. /************************************************************************/
  191. /*      fileType() gets file type for MSDOS                             */
  192. /************************************************************************/
  193. fileType(char *theDir)
  194.   {
  195.   FILE *fd;
  196.   Do_Stack_Check();
  197.   if (strchr(theDir, '*') != NULL ||
  198.   strchr(theDir, '?') != NULL)
  199.     {
  200.     return AMB_FILE;
  201.  
  202.     }
  203.   if (realSetSpace(theDir))
  204.     {
  205.     homeSpace();
  206.     return IS_DIR;
  207.  
  208.     }
  209.   if ((fd = safeopen(theDir, READ_TEXT)) != NULL)
  210.     {
  211.     fclose(fd);
  212.     return SINGLE_FILE;
  213.  
  214.     }
  215.   return NO_IDEA;
  216.  
  217.   }
  218. /************************************************************************/
  219. /*      goodArea() Gets a valid path from the sysop. Drive should be    */
  220. /*                  set already.                                        */
  221. /************************************************************************/
  222. goodArea(char *prompt, char *dir)
  223.   {
  224.   int  c;
  225.   char dir_x[150];
  226.   Do_Stack_Check();
  227.   while (TRUE)
  228.     {
  229.     if (!getXString(prompt, dir_x, 149, "", ""))
  230.     return FALSE;
  231.     c = fileType(dir_x);
  232.     switch (c)
  233.       {
  234.       case IS_DIR:
  235.       strCpy(dir, dir_x);
  236.       return TRUE;
  237.       case NO_IDEA:
  238.       if (strLen(dir_x) != 0)
  239.         {
  240.         Output_Citadel_Message("DNTEXS",(long)dir_x,NULL,NULL);
  241.         if (getYesNo("CREATE"))
  242.           {
  243.           if (mkdir(dir_x) != 0)
  244.             {
  245.             Output_Citadel_Message("ERRDIR",(long)dir_x,NULL,NULL);
  246.             homeSpace();
  247.  
  248.             }
  249.           else
  250.             {
  251.             homeSpace();
  252.             strCpy(dir, dir_x);
  253.             return TRUE;
  254.  
  255.             }
  256.  
  257.           }
  258.  
  259.         }
  260.       else
  261.         {
  262.         strCpy(dir, dir_x);
  263.         return TRUE;
  264.  
  265.         }
  266.       break;
  267.       default:
  268.         Output_Citadel_Message("ERRNDR",(long)dir_x,NULL,NULL);
  269.       }
  270.  
  271.     }
  272.  
  273.   }
  274. /************************************************************************/
  275. /*      homeSpace() takes us home!                                      */
  276. /************************************************************************/
  277. void homeSpace()
  278.   {
  279.   Do_Stack_Check();
  280.   realSetSpace(ourHomeSpace);
  281.   }
  282. /************************************************************************/
  283. /*      netGetArea() Get area to store a file from networking           */
  284. /************************************************************************/
  285. netGetAreaV2(MenuId id,char *fn, struct fl_req *file_data, char ambiguous)
  286.   {
  287.   char goodname;
  288.   Do_Stack_Check();
  289.   if (!goodArea("DIRNSY", file_data->flArea.naDirname)) return FALSE;
  290.   if (!ambiguous)
  291.     {
  292.     realSetSpace(file_data->flArea.naDirname);
  293.     do
  294.       {
  295.       if (!getXString("FILNSY",file_data->filename, NAMESIZE, fn, fn))
  296.         {
  297.         homeSpace();
  298.         return FALSE;
  299.  
  300.         }
  301.       if (access(file_data->filename, 0) == 0)
  302.         {
  303.         Output_Citadel_Message("AREXTS",(long)file_data->filename,NULL,NULL);
  304.         goodname = SysopGetYesNo(id,"ISTHIS","THEPRM");
  305.  
  306.         }
  307.       else goodname = TRUE;
  308.  
  309.       }
  310.     while (!goodname);
  311.     homeSpace();
  312.  
  313.     }
  314.   else
  315.     {
  316.     Output_Citadel_Message("AMBFRS",NULL,NULL,NULL);
  317.     file_data->filename[0] = 0;
  318.     return FALSE;
  319.     }
  320.   return TRUE;
  321.  
  322.   }
  323. /************************************************************************/
  324. /*      prtNetArea() human readable form of a NET_AREA                  */
  325. /************************************************************************/
  326. char *prtNetArea(NET_AREA *netArea)
  327.   {
  328.   Do_Stack_Check();
  329.   return netArea->naDirname;
  330.  
  331.   }
  332. /************************************************************************/
  333. /*      dirString() a directory string                                                                          */
  334. /************************************************************************/
  335. void dirString(char *target, ROOM_AREA *area)
  336.   {
  337.   char *temp;
  338.   Do_Stack_Check();
  339.   if ((temp = FindDirName(*area)) != NULL)
  340.   strCpy(target, temp);
  341.   else strCpy(target, "ERROR");
  342.  
  343.   }
  344. /************************************************************************/
  345. /*      realSetSpace() does work of setSpace                            */
  346. /************************************************************************/
  347. char currentdir[150];
  348. char realSetSpace(char *dir)
  349.   {
  350.   extern FILE *netLog;
  351.   char result;
  352.   Do_Stack_Check();
  353.   if (cfg.BoolFlags.debug)
  354.     {
  355.     splitF(netLog,"Changing from %s\n",currentdir);
  356.     splitF(netLog,"To:%s\n",dir);
  357.     };
  358.   strcpy(currentdir,dir);
  359.   SpecialMessage(dir);
  360.   result = (char )(chdir(dir)== 0 );
  361.   return result;
  362.   }
  363. /************************************************************************/
  364. /*      FindDirName() finds the directory associated with some room     */
  365. /************************************************************************/
  366. char *FindDirName(int roomNo)
  367.   {
  368.   Do_Stack_Check();
  369.   return (char *)
  370.   SearchList(&DirBase, NtoStrInit(roomNo, "", 0, TRUE));
  371.  
  372.   }
  373. /************************************************************************/
  374. /*      setSpace() moves us to an area                                  */
  375. /************************************************************************/
  376. char setSpace(aRoom *roomData)
  377.   {
  378.   char   *temp;
  379.   extern SListBase DirBase;
  380.   Do_Stack_Check();
  381.   if ((temp = FindDirName(roomData->rbArea)) == NULL)
  382.     {
  383.     Output_Citadel_Message("ERRDRM",NULL,NULL,NULL);
  384.     return FALSE;
  385.  
  386.     }
  387.   if (!realSetSpace(temp))
  388.     {
  389.     Output_Citadel_Message("ERRDME",(long)temp,NULL,NULL);
  390.     return FALSE;
  391.  
  392.     }
  393.   return TRUE;
  394.  
  395.   }
  396. #ifdef READY
  397. /************************************************************************/
  398. /*      writeArea(x) prints the area associated with this room          */
  399. /************************************************************************/
  400. void writeArea(char rightNow, aRoom *roomData, char *buf)
  401.   {
  402.   Do_Stack_Check();
  403.   if (rightNow)
  404.   mPrintf("%s\n ", FindDirName(roomData->rbArea));
  405.   else
  406.     {
  407.     if (strLen(FindDirName(roomData->rbArea)) != 0)
  408.     sPrintf(buf, "'%s'", FindDirName(roomData->rbArea));
  409.     else
  410.     sPrintf(buf, "'%c:'", locDisk);
  411.  
  412.     }
  413.  
  414.   }
  415. #endif
  416. /************************************************************************/
  417. /*      sysGetSendFiles() where to find files to send to another system */
  418. /************************************************************************/
  419. char sysGetSendFilesV2(MenuId id,char *name, struct fl_send *sendWhat)
  420.   {
  421.   Do_Stack_Check();
  422.   strCpy(sendWhat->snArea.naDirname, name);
  423.   if (fileType(sendWhat->snArea.naDirname) == NO_IDEA)
  424.     {
  425.     if (SysopGetYesNo(id,NULL,"FILDIR"))
  426.     return TRUE;
  427.     return FALSE;
  428.  
  429.     }
  430.   return TRUE;
  431.  
  432.   }
  433. /************************************************************************/
  434. /*      MoveFile() move a file to a new name and location               */
  435. /************************************************************************/
  436. void MoveFile(char *oldname, char *newname)
  437.   {
  438.   char buffer[100];
  439.   FILE *infd, *outfd;
  440.   int s;
  441.   Do_Stack_Check();
  442.   if (toUpper(*oldname) == toUpper(*newname))
  443.     {
  444.     rename(oldname, newname);
  445.     if (access(newname, 0) == 0) return;
  446.  
  447.     }
  448.   sPrintf(buffer, "copy >NIL: %s %s", oldname, newname);
  449.   Jsystem(buffer);
  450.   if (access(newname, 0) == 0)
  451.     {
  452.     unlink(oldname);
  453.  
  454.     }
  455.   else
  456.     {
  457.     if ((infd = safeopen(oldname, READ_ANY)) == NULL) return;
  458.     if ((outfd = safeopen(newname, WRITE_ANY)) == NULL)
  459.       {
  460.       fclose(infd);
  461.       return;
  462.  
  463.       }
  464.     while ((s = fread(buffer, sizeof buffer, 1, infd)) > 0)
  465.     fwrite(buffer, s, 1, outfd);
  466.     fclose(infd);
  467.     fclose(outfd);
  468.     unlink(oldname);
  469.  
  470.     }
  471.  
  472.   }
  473. /************************************************************************/
  474. /*      sysRoomLeft() how much room left in net recept area             */
  475. /************************************************************************/
  476. long sysRoomLeft()
  477.   {
  478.   long temp, temp2, temp3;
  479.   Do_Stack_Check();
  480.   temp = (long) ( (long) cfg.sizeArea * 1024);
  481.   netBytes = 0l;
  482.   doSendWork(ALL_FILES, getSize);
  483.   diskSpaceLeft(NULL, &temp3, &temp2);
  484.   return (minimum(temp - netBytes, temp2));
  485.  
  486.   }
  487. /************************************************************************/
  488. /*      sysSendFiles() system dep stuff for sending files               */
  489. /************************************************************************/
  490. void sysSendFiles(struct fl_send *sendWhat)
  491.   {
  492.   char   temp[100], *last;
  493.   label  mask;
  494.   Do_Stack_Check();
  495.   strCpy(temp, sendWhat->snArea.naDirname);
  496.   switch (fileType(sendWhat->snArea.naDirname))
  497.     {
  498.     case IS_DIR:
  499.     strCpy(mask, "*");
  500.     break;
  501.     case SINGLE_FILE:
  502.     case AMB_FILE:
  503.     if ((last = strrchr(temp, '/')) == NULL &&
  504.     (last = strrchr(temp, ':')) == NULL)
  505.       {
  506.       strCpy(mask, temp);
  507.       temp[0] = 0;
  508.  
  509.       }
  510.     else
  511.       {
  512.       strCpy(mask, last + 1);
  513.       if (last != temp && *last != ':')
  514.       *last = 0;
  515.       else
  516.       *(last + 1) = 0;
  517.  
  518.       }
  519.     break;
  520.     case NO_IDEA:
  521.     default:
  522.     sPrintf(temp, "Couldn't do anything with '%s'.",
  523.     sendWhat->snArea.naDirname);
  524.     netResult(temp);
  525.     return;
  526.  
  527.     }
  528.   if (!realSetSpace(temp))
  529.     {
  530.     sPrintf(msgBuf.mbtext, "Send file didn't know what to do with %s.",
  531.     temp);
  532.     netResult(msgBuf.mbtext);
  533.  
  534.     }
  535.   else
  536.   doSendWork(mask, netSendFile);
  537.   homeSpace();
  538.  
  539.   }
  540. /************************************************************************/
  541. /*      doSendWork() does work of sysSendFiles()                        */
  542. /************************************************************************/
  543. void doSendWork(char *filename, void (*fn)(DirEntry *f))
  544.   {
  545.   Do_Stack_Check();
  546.   wildCard(fn, filename, FALSE, "", FALSE);
  547.  
  548.   }
  549. /************************************************************************/
  550. /*      DoDomainDirectory() work on a domain directory                  */
  551. /************************************************************************/
  552. void DoDomainDirectory(int i, char kill)
  553.   {
  554.   char num[8];
  555.   DOMAIN_FILE name;
  556.   Do_Stack_Check();
  557.   sPrintf(num, "%d", i);
  558.   makeSysName(name, num, &cfg.domainArea);
  559.   if (kill) rmdir(name);
  560.   else      mkdir(name);
  561.  
  562.   }
  563. /************************************************************************/
  564. /* Section 3.5. BAUD HANDLER:                                           */
  565. /*    The code in here has to discover what baud rate the caller is at. */
  566. /* For some computers, this should be ridiculously easy.                */
  567. /************************************************************************/
  568. #define NO_GOOD         0
  569. #define CR_CAUGHT       1
  570. #define NET_CAUGHT      2
  571. #define STROLL_CAUGHT   3
  572. /************************************************************************/
  573. /*      check_CR() Checks for CRs from the data port for half a second. */
  574. /************************************************************************/
  575. static short crcnt;
  576. static short timer1,timer2;
  577. char check_CR()
  578.   {
  579.   extern FILE *netLog;
  580.   struct timePacket ff;
  581.   int c=0;
  582.   int  clcnt=0;
  583.   char clast[8];  /* debug: last eight characters */
  584.   memset(clast,0,8);
  585.   Do_Stack_Check();
  586.   setTimer(&ff);
  587.   while (milliTimeSince(&ff) < timer1 )
  588.     {
  589.     if (MIReady())
  590.       {
  591.       if( c != 13 )crcnt = 0;
  592.       clast[clcnt & 0x07] = c = inp();
  593.       clcnt++;
  594.       switch (c)
  595.         {
  596.         case 27: return CR_CAUGHT;break;  /* one escape, or two CRs */
  597.         case 13:                          /* cr from user?, must have 2 */
  598.         if( ++crcnt >1)
  599.           {
  600.           return CR_CAUGHT;
  601.           };
  602.         break;
  603.         case 7:
  604.         if (cfg.BoolFlags.netParticipant)
  605.           {
  606.           if (receive(1) == 13)
  607.             {
  608.             crcnt = 1;
  609.             if (receive(1) == 69)
  610.               {
  611.               return NET_CAUGHT;
  612.               };
  613.             };
  614.           };
  615.         break;
  616.         case 68:
  617.         if (receive(1) == 79)
  618.           {
  619.           if (receive(1) == 35)
  620.             {
  621.             return STROLL_CAUGHT;
  622.             };
  623.           };
  624.         break;
  625.         default:
  626.         if (clcnt > 0 && cfg.BoolFlags.debug)
  627.           {
  628.           splitF(netLog,"%x %x %x %x\n ",clast[0],clast[1],clast[2],clast[3]);
  629.           splitF(netLog,"%x %x %x %x\n ",clast[4],clast[5],clast[6],clast[7]);
  630.           };
  631.         };
  632.       };
  633.     };
  634.   return NO_GOOD;
  635.   }
  636. /************************************************************************/
  637. /*      Find_Baud() Finds the baud from sysop and user supplied data.   */
  638. /************************************************************************/
  639. char Find_baud(char **whatRate)
  640.   {
  641.   char noGood = NO_GOOD;
  642.   int  Time = 0;
  643.   long  baudRunner;                    /* Only try for 60 seconds      */
  644.   char flag;
  645.   extern FILE *netLog;
  646.   extern long byteRate;
  647.   crcnt = 0;
  648.   Do_Stack_Check();
  649.   *whatRate = rates[9];  /* default to unknown */
  650.   flag = FALSE;
  651.   if ((baudRunner = (long)getModemId()) != ERROR)
  652.     {
  653.     CitadelBaudRate(baudRunner, "Find_baud");
  654.     flag = TRUE;
  655.     if (cfg.BoolFlags.debug) splitF(netLog, "getModemId = %d\n",baudRunner);
  656.     };
  657.   if (cfg.DepData.LockPort >= 0 && !flag)  /* if serial port locked, use it */
  658.     {
  659.     baudRunner = cfg.DepData.LockPort;
  660.     flag = TRUE;
  661.     if (cfg.BoolFlags.debug) splitF(netLog, "LockPort Forced = %d\n",baudRunner);
  662.     };
  663.   pause(10);                    /* To clear line noise and eat banner */
  664.   while (MIReady())   inp();   /* eat noise and banners        */
  665.   if( cfg.DepData.LockPort >= 0 || flag )
  666.     {
  667.     timer1 = 50;               /* time spent looking for User/Net session */
  668.     timer2 =  4;               /* number of autobaud attempts */
  669.     }
  670.   else
  671.     {
  672.     timer1 = 75;                /* time spent looking for User/Net session */
  673.     timer2 = (cfg.sysBaud+1)*3; /* autobaud attempts, try 3 attempts */
  674.     baudRunner = 0;
  675.     };
  676.   while (gotCarrier() && noGood == NO_GOOD &&  (Time < timer2))
  677.     {
  678.     Time++;
  679.     if( !flag )
  680.       {
  681.       CitadelBaudRate(baudRunner,"Find_baud");
  682.       };
  683.     noGood = check_CR();
  684.     if (noGood == NO_GOOD && !flag)
  685.       {
  686.       if( baudRunner++ > cfg.sysBaud )baudRunner = 0;
  687.       };
  688.     };
  689.   if( noGood == NO_GOOD && !flag )
  690.     {
  691.     baudRunner = cfg.sysBaud;
  692.     if( !flag ) CitadelBaudRate(baudRunner, "Find_baud");
  693.     };
  694.   LastBaudIndex = baudRunner;
  695.   *whatRate = rates[baudRunner];
  696.   byteRate =  (atol(rates[baudRunner]) ) / 10L;
  697.   if (cfg.BoolFlags.debug) splitF(netLog, "Time:%d Baud:%s\n",Time,*whatRate);
  698.   if (noGood == NET_CAUGHT)
  699.     {
  700.     netController(0, 0, NO_NETS, ANY_CALL, 0);
  701.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->Net_Caught\n",*whatRate);
  702.     return FALSE;       /* pretend nothing happened */
  703.  
  704.     }
  705.   if (noGood == STROLL_CAUGHT)
  706.     {
  707.     StrollIt();
  708.     if (cfg.BoolFlags.debug) splitF(netLog, "Baud -%s-->STROLL_Caught\n",*whatRate);
  709.     return FALSE;       /* pretend nothing happened */
  710.  
  711.     }
  712.   if (cfg.BoolFlags.debug) splitF(netLog, "Baud-%s-->other\n",*whatRate);
  713.   return (char)(noGood == CR_CAUGHT || flag); /* return TRUE if USER */
  714.  
  715.   }
  716. /************************************************************************/
  717. /*      getModemId() Try to read baud id from modem                     */
  718. /************************************************************************/
  719. #define BA_BUF_SIZE     80
  720.   extern char results_debug;  /* turn on to debug modem results codes */
  721.   extern char results_cid;    /* turn on to collect caller ID info if present */
  722.  
  723. int getModemId()
  724.   {
  725.   char c, buffer[BA_BUF_SIZE];         /* Hopefully, overkill */
  726.   extern FILE *netLog;
  727.   struct timePacket ff;
  728.   int i;
  729.   char save_all = FALSE;
  730.   UNS_16 *j;
  731.   extern char ResultCodesAvailable;
  732.   Do_Stack_Check();
  733.   if (!ResultCodesAvailable) return ERROR;
  734.   setTimer(&ff);
  735.   i = 0;
  736.   while (timeSince(&ff) < 5l)
  737.     {
  738.     if (MIReady())
  739.       {
  740.       if ((c = inp()) == '\r')
  741.         {
  742.         buffer[i] = 0;
  743.         if( i <= 1 )continue;
  744.         if( buffer[0] == 'E' && buffer[1]== 07 )return ERROR;
  745.         if( results_debug )splitF(NULL, "buffer search:-%s-\n",buffer);
  746.         if( save_all )splitF(NULL, "CID:%s\n",buffer);
  747.         j = (int *) SearchList(&ResList, buffer);
  748.         if (j != NULL)
  749.           {
  750.           switch (*j)
  751.             {
  752.             case R_RING:
  753.               if( results_cid )  /* toggle to collect info between rings */
  754.                 {
  755.                 save_all = TRUE;
  756.                 };
  757.               break;
  758.             case R_AOK:      break;
  759.             case R_NOCARR:
  760.             case R_BUSY:
  761.             case R_DIAL:
  762.             case R_NODIAL:   return ERROR;
  763.             case R_300:
  764.             case R_1200:
  765.             case R_2400:
  766.             case R_4800:
  767.             case R_9600:
  768.             case R_14400:
  769.             case R_19200:
  770.             case R_38400:
  771.             case R_57600:
  772.             return (int)*j;
  773.             default:
  774.               splitF(NULL, "Modem text not in RESULTS.SYS\n");
  775.             break;
  776.  
  777.             };
  778.           i = 0;
  779.  
  780.           }
  781.         else i = 0;
  782.  
  783.         }
  784.       else
  785.         {
  786.         if (c != '\n')
  787.           {
  788.           buffer[i++] = c;
  789.           }
  790.         if (i >= BA_BUF_SIZE - 4)
  791.           {
  792.           /* Fudge factor */
  793.           i = 0;
  794.           if( results_debug )splitF(NULL, "buffer flush:-%s-\n",buffer);
  795.  
  796.           }
  797.  
  798.         }
  799.  
  800.       }
  801.  
  802.     }
  803.   buffer[i] = 0;      /* debug for now */
  804.   splitF(NULL, "FAILURE to find in RESULTS.SYS:%s\n", buffer);
  805.   return ERROR;
  806.  
  807.   }
  808. /************************************************************************/
  809. /*      getNetBaud()  gets baud of network caller -- refer to SysDep.doc*/
  810. /************************************************************************/
  811. char getNetBaud()
  812.   {
  813.   extern FILE *netLog;
  814.   long   Time, baudRunner;
  815.   extern long byteRate;
  816.   char        found = FALSE, notFinished;
  817.   extern char inNet;
  818.   Do_Stack_Check();
  819.   /* If anytime answer, then we already have baud rate */
  820.   if (inNet == ANY_CALL || inNet == STROLL_CALL)
  821.     {
  822.     found      = TRUE;
  823.     baudRunner = LastBaudIndex;
  824.  
  825.     }
  826.   else if (GetFirst(&ResList))
  827.     {
  828.     if ((baudRunner = getModemId()) != ERROR)
  829.       {
  830.       found = TRUE;
  831.  
  832.       }
  833.  
  834.     }
  835.   pause(10);         /* Pause a  second */
  836.   if (found)
  837.     {
  838.     CitadelBaudRate(baudRunner, "getNetBaud");
  839.     byteRate = atol(rates[baudRunner]) / 10L;
  840.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  841.       {
  842.       if (check_for_init(FALSE)) return TRUE;
  843.       }
  844.     if (gotCarrier())
  845.       {
  846.       outFlag = IMPERVIOUS;
  847.       Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  848.  
  849.       }
  850.  
  851.     }
  852.   else
  853.     {
  854.     while (MIReady())   inp();          /* Clear garbage        */
  855.     for (Time = 0; gotCarrier() && Time < 25; Time++)
  856.       {
  857.       for (notFinished = TRUE, baudRunner = 0;
  858.       gotCarrier() && notFinished;)
  859.         {
  860.         byteRate = atol(rates[baudRunner]) / 10L;
  861.         CitadelBaudRate(baudRunner, "getNetBaud");
  862.         if (check_for_init(FALSE)) return TRUE;  /* get connection */
  863.         notFinished = !(baudRunner == cfg.sysBaud);
  864.         baudRunner++;
  865.  
  866.         }
  867.  
  868.       }
  869.     if (gotCarrier())
  870.       {
  871.       outFlag = IMPERVIOUS;
  872.       for (baudRunner = cfg.sysBaud; baudRunner > -1; baudRunner--)
  873.         {
  874.         CitadelBaudRate(baudRunner, "getNetBaud");
  875.         Output_Citadel_Message("LATERN",timeLeft(),NULL,NULL);
  876.         }
  877.       outFlag = OUTOK;
  878.  
  879.       }
  880.  
  881.     }
  882.   if (!gotCarrier()) splitF(netLog, "GetNetBaud:Lost carrier\n");
  883.   killConnection();
  884.   return FALSE;
  885.  
  886.   }
  887. /************************************************************************/
  888. /* Section 3.3. CONSOLE HANDLING:                                       */
  889. /*    These functions are responsible for handling console I/O.         */
  890. /************************************************************************/
  891. /************************************************************************/
  892. /*      mputChar()                                                      */
  893. /************************************************************************/
  894.  
  895. int ConPutChar(char myChar);
  896.  
  897. void mputChar(char c)
  898.   {
  899.   extern char ChatMode;
  900.   Do_Stack_Check();
  901.   if ((c == '\0') || (c == BELL && cfg.BoolFlags.noChat && !onConsole))
  902.   return;
  903.   if (!(whichIO == CONSOLE || onConsole) && !anyEcho)
  904.   return;
  905.   if (c != ESC &&       (echo == BOTH ||
  906.   (whichIO == CONSOLE && (echo != NEITHER || echoChar))))
  907.     {
  908.     ConPutChar(c);
  909.  
  910.     }
  911.   if (onConsole && !ChatMode && ConDelay > 0) pause(ConDelay);
  912.  
  913.   }
  914.